#include "dialogmain.h"
#include "ui_dialogmain.h"
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDesktopWidget>
#include <QFile>
#include <QGridLayout>
#include <QMenu>
#include <QMessageBox>
#include <QSettings>
#include <QTimer>
#include "buttonrelay.h"
#include "serversettingsdialog.h"

DialogMain::DialogMain(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogMain)
{
    ui->setupUi(this);

    loadConfig(QCoreApplication::applicationDirPath() + "/" + DEF_INI_FILENAME);

    initContextMenu();
    initWidget();
    initTcpSocket();

    mOneSecondTimerId = startTimer(1000);

    mActionSettingsDialog = NULL;
}

DialogMain::~DialogMain()
{
    if (mOneSecondTimerId) {
        killTimer(mOneSecondTimerId);
        mOneSecondTimerId = 0;
    }

    saveConfig(QCoreApplication::applicationDirPath() + "/" + DEF_INI_FILENAME);

    if (mActionSettingsDialog) {
        delete mActionSettingsDialog;
        mActionSettingsDialog = NULL;
    }

    delete ui;
}

void DialogMain::timerEvent(QTimerEvent *e)
{
    if (e->timerId() == mOneSecondTimerId) {
        static int _oldSecond = 0;
        QDateTime curDateTime = QDateTime::currentDateTime();

        if (2014 <= curDateTime.date().year()) {
            if (curDateTime.time().second() != _oldSecond) {
                _oldSecond = curDateTime.time().second();

                if (0 == _oldSecond) {
                    //QTimer::singleShot(1, this, SLOT(onMinuteProc()));
                }
            }
        }
    }
}

#ifdef  Q_OS_WIN32
typedef struct tagPOINT {
    quint32   x;
    quint32   y;
} POINT, *PPOINT;
typedef struct tagMSG2 {
    HWND      hwnd;
    quint32   message;
    quint32   wParam;
    quint32   lParam;
    quint32   time;
    POINT     pt;
} MSG2, *PMSG2, *LPMSG2;
#define WM_POWERBROADCAST       0x218
#define PBT_APMSUSPEND          0x4
#define PBT_APMRESUMESUSPEND    0x7
#define PBT_APMRESUMEAUTOMATIC  0x12
#endif  //Q_OS_WIN32
bool DialogMain::winEvent(MSG *message, long *result)
{
    Q_UNUSED(result);
#ifdef  Q_OS_WIN32
    PMSG2 pMsg = (PMSG2)message;
    if (WM_POWERBROADCAST == pMsg->message) {
        qDebug() << pMsg->wParam << "," << pMsg->lParam << "," << pMsg->time;
        if (PBT_APMRESUMEAUTOMATIC == pMsg->wParam) {
            QTimer::singleShot(10, this, SLOT(onTcpConnect()));
        }
    }
#else
    Q_UNUSED(message);
#endif  //Q_OS_WIN32

    return false;
}

void DialogMain::onParseArgs(const QString& args)
{
    qDebug() << args;
    if (0 == args.compare("quit")) {
        qApp->quit();
    } else {
        emit signalNeedToShow();
    }
}

QWidget *g_ButtonWidget = NULL;
void DialogMain::onShowContextMenu(const QPoint& pos)
{
    QWidget *widget = childAt(pos);
    for (int i=0; i<mLayout.mButtons.size(); i++) {
        if (mLayout.mButtons[i].mWidget == widget) {
            g_ButtonWidget = widget;

            QMenu* contextMenu = new QMenu(this);
            contextMenu->addAction(tr("OFF"), this, SLOT(onMenuRelayOff()));
            contextMenu->addSeparator();
            if (RELAY_TYPE_RELAY == mLayout.mButtons[i].mRType) {
                contextMenu->addAction(tr("ON"), this, SLOT(onMenuRelayOn()));
            } else {
                int flagRemote = (mLayout.mButtons[i].mRType / 100);
                int isHeating = (mLayout.mButtons[i].mRType / 10) % 10;
                if (0 == flagRemote) {
                    contextMenu->addAction(tr("송풍"), this, SLOT(onMenuRelayAir()));
                    contextMenu->addSeparator();
                }
                if (isHeating) {
                    contextMenu->addAction(tr("난방"), this, SLOT(onMenuRelayHeating()));
                } else {
                    contextMenu->addAction(tr("냉방"), this, SLOT(onMenuRelayCooling()));
                }
            }
            contextMenu->exec(mapToGlobal(pos));
            delete contextMenu;
            return;
        }
    }
    g_ButtonWidget = NULL;

    QMenu* contextMenu = new QMenu(this);
    contextMenu->addAction(tr("서버 설정"), this, SLOT(onMenuSocketServer()));
    //contextMenu->addAction(tr("서버 동기화"), this, SLOT(onMenuSync()));
    contextMenu->addSeparator();
    //contextMenu->addAction(tr("서버 재시작"), this, SLOT(onMenuReboot()));
    //contextMenu->addSeparator();
    contextMenu->addAction(tr("타이머 설정"), this, SLOT(onMenuActionSetting()));
    contextMenu->addSeparator();
    {
        QMenu* subMenu = new QMenu(tr("옵션"), contextMenu);
        subMenu->addAction(tr("냉방모드"), this, SLOT(onMenuOptionCooling()));
        subMenu->addAction(tr("난방모드"), this, SLOT(onMenuOptionHeating()));

        contextMenu->addMenu(subMenu);
        contextMenu->addSeparator();
    }
    contextMenu->addAction(tr("프로그램 종료"), this, SLOT(onMenuExit()));
    contextMenu->exec(mapToGlobal(pos));
    delete contextMenu;
}

void DialogMain::onMenuRelayOff()
{
    if (g_ButtonWidget && mIsSocketInit) {
        ButtonRelay *buttonRelay = (ButtonRelay *)g_ButtonWidget;
        // $set:[cid,bid,rid,status,],$
        QString packet("$set:");
        packet += QString("[%1,%2,%3,%4,],").arg(buttonRelay->button()->mCId)
                .arg(buttonRelay->button()->mBId).arg(buttonRelay->button()->mRId).arg(RELAY_STATUS_OFF);
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuRelayOn()
{
    if (g_ButtonWidget && mIsSocketInit) {
        ButtonRelay *buttonRelay = (ButtonRelay *)g_ButtonWidget;
        // $set:[cid,bid,rid,status,],$
        QString packet("$set:");
        packet += QString("[%1,%2,%3,%4,],").arg(buttonRelay->button()->mCId)
                .arg(buttonRelay->button()->mBId).arg(buttonRelay->button()->mRId).arg(RELAY_STATUS_ON);
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuRelayAir()
{
    if (g_ButtonWidget && mIsSocketInit) {
        ButtonRelay *buttonRelay = (ButtonRelay *)g_ButtonWidget;
        // $set:[cid,bid,rid,status,],$
        QString packet("$set:");
        packet += QString("[%1,%2,%3,%4,],").arg(buttonRelay->button()->mCId)
                .arg(buttonRelay->button()->mBId).arg(buttonRelay->button()->mRId).arg(RELAY_STATUS_AIR);
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuRelayCooling()
{
    if (g_ButtonWidget && mIsSocketInit) {
        ButtonRelay *buttonRelay = (ButtonRelay *)g_ButtonWidget;
        // $set:[cid,bid,rid,status,],$
        QString packet("$set:");
        packet += QString("[%1,%2,%3,%4,],").arg(buttonRelay->button()->mCId)
                .arg(buttonRelay->button()->mBId).arg(buttonRelay->button()->mRId).arg(RELAY_STATUS_COOLING);
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuRelayHeating()
{
    if (g_ButtonWidget && mIsSocketInit) {
        ButtonRelay *buttonRelay = (ButtonRelay *)g_ButtonWidget;
        // $set:[cid,bid,rid,status,],$
        QString packet("$set:");
        packet += QString("[%1,%2,%3,%4,],").arg(buttonRelay->button()->mCId)
                .arg(buttonRelay->button()->mBId).arg(buttonRelay->button()->mRId).arg(RELAY_STATUS_HEATING);
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuSocketServer()
{
    ServerSettingsDialog dlg(mSocketServer.mAddress, mSocketServer.mPortNum, mUserInfo.mUserId, mUserInfo.mPassword, this);
    if (QDialog::Accepted == dlg.exec()) {
        mSocketServer.mAddress = dlg.address();
        mSocketServer.mPortNum = dlg.portNum();
        mUserInfo.mUserId = dlg.userId();
        mUserInfo.mPassword = dlg.password();
        qDebug() << mSocketServer.mAddress << mSocketServer.mPortNum << mUserInfo.mUserId << mUserInfo.mPassword;

        if (mSocketServer.mAddress.length() && mSocketServer.mPortNum.length()) {
            QTimer::singleShot(10, this, SLOT(onTcpConnect()));
        }
    }
}

void DialogMain::onMenuSync()
{
    if (mIsSocketInit) {
        // $sync:,$
        QString packet("$sync:,$");
        qDebug() << packet;

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuReboot()
{
    if (mIsSocketInit) {
        // $reboot:,$
        QString packet("$reboot:,$");
        qDebug() << packet;

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuActionSetting()
{
    if (mIsSocketInit) {
        // $getfile:filename,$
        QString packet("$getfile:");
        packet += QString("%1,").arg(DEF_XML_ACTION);
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuOptionCooling()
{
    if (mIsSocketInit) {
        // $option:[,],[,],$
        QString packet("$option:[1,0,],$");
        qDebug() << packet;

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuOptionHeating()
{
    if (mIsSocketInit) {
        // $option:[,],[,],$
        QString packet("$option:[1,1,],$");
        qDebug() << packet;

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onMenuExit()
{
    qApp->quit();
}

void DialogMain::onButtonClicked()
{
    if (mIsSocketInit) {
        if (false == sender()->isWidgetType()) {
            return;
        }
        ButtonRelay *buttonRelay = (ButtonRelay *)sender();
        int status = -1;

        qDebug() << buttonRelay->button()->mName << buttonRelay->button()->mRType << buttonRelay->button()->mStatus;
        switch (buttonRelay->button()->mStatus) {
        case RELAY_STATUS_OFF:
            status = RELAY_STATUS_ON;
            break;
        case RELAY_STATUS_ON:
            if (RELAY_TYPE_RELAY != buttonRelay->button()->mRType) {
                int isHeating = (buttonRelay->button()->mRType / 10) % 10;
                status = isHeating ? RELAY_STATUS_HEATING : RELAY_STATUS_COOLING;
            } else {
                status = RELAY_STATUS_OFF;
            }
            break;
        case RELAY_STATUS_AIR:
            if (RELAY_TYPE_RELAY != buttonRelay->button()->mRType) {
                status = RELAY_STATUS_OFF;
            }
            break;
        case RELAY_STATUS_COOLING:
        case RELAY_STATUS_HEATING:
            if (RELAY_TYPE_RELAY != buttonRelay->button()->mRType) {
                int flagRemote = (buttonRelay->button()->mRType / 100);
                if (flagRemote) {
                    // off - on - cooling/heating - off
                    status = RELAY_STATUS_OFF;
                } else {
                    // off - on - cooling/heating - air - off
                    status = RELAY_STATUS_AIR;
                }
            }
            break;
        case RELAY_STATUS_PENDING:
            break;
        case RELAY_STATUS_UNKNOWN:
            status = RELAY_STATUS_UNKNOWN;	// for getStatus
            break;
        case RELAY_STATUS_NOTUSED:
            break;
        }

        if (-1 < status) {
            // $set:[cid,bid,rid,status,],$
            QString packet("$set:");
            packet += QString("[%1,%2,%3,%4,],").arg(buttonRelay->button()->mCId).arg(buttonRelay->button()->mBId).arg(buttonRelay->button()->mRId).arg(status);
            packet += "$";

            qDebug() << packet;
            mpTcpSoceket->write(packet.toUtf8());
        }
    }
}

void DialogMain::onActionSettingsDialogShow(bool show)
{
    if (show) {
        mActionSettingsDialog->show();
        mActionSettingsDialog->raise();
        mActionSettingsDialog->activateWindow();
    } else {
        mActionSettingsDialog->hide();

        QString fileData = mAction.save(QCoreApplication::applicationDirPath() + "/" + DEF_XML_ACTION);

        // $sendfile:filename,filesize,filedata$
        QString packet("$sendfile:");
        packet += QString("%1,").arg(DEF_XML_ACTION);
        packet += QString("%1,").arg(fileData.length());
        packet += fileData;
        packet += "$";

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onTcpConnect()
{
    mIsSocketInit = false;

    if (mpTcpSoceket->isOpen()) {
        mpTcpSoceket->abort();
    }

    qDebug() << mSocketServer.mAddress << ":" << mSocketServer.mPortNum;
    mpTcpSoceket->connectToHost(mSocketServer.mAddress, mSocketServer.mPortNum.toInt());
}

void DialogMain::onTcpConnected()
{
    qDebug() << "onTcpConnected() : " << mpTcpSoceket->state();
    if (QAbstractSocket::ConnectedState == mpTcpSoceket->state()) {
        mIsSocketInit = true;
        mTcpSoceketRecv.clear();

        QString packet = "$login:";
        packet += QString("%1,").arg(mUserInfo.mUserId);
        packet += QString("%1,").arg(mUserInfo.mPassword);
        packet += "$";
        qDebug() << packet;

        mpTcpSoceket->write(packet.toUtf8());
    }
}

void DialogMain::onTcpRead()
{
    QByteArray byteArry;
    while (mpTcpSoceket->bytesAvailable()) {
        byteArry += mpTcpSoceket->readAll();
    }

    mTcpSoceketRecv += QString::fromUtf8(byteArry);
    while('$' != mTcpSoceketRecv.at(0)) {
        mTcpSoceketRecv.remove(0, 1);
    }

    QString packet;
    int firstIdx = 0;
    int lastIdx = mTcpSoceketRecv.lastIndexOf('$');
    if (0 < lastIdx) {
        packet = mTcpSoceketRecv.left(lastIdx+1);
        mTcpSoceketRecv.remove(0, lastIdx+1);
    }
    qDebug() << "onTcpRead(" << packet.length() << ") :" << packet;

    if (packet.length()) {
        int findIdx, curIdx = firstIdx + 1;
        QString cmd;

        findIdx = packet.indexOf(':', curIdx);
        cmd = packet.mid(curIdx, (findIdx-curIdx));
        curIdx = findIdx + 1;

        if (!cmd.compare("layout")) {
            // $layout:cx,cy,row,column,[...],[...],$
            mLayout.mButtons.clear();

            findIdx = packet.indexOf(',', curIdx);
            mLayout.mCX = packet.mid(curIdx, (findIdx-curIdx)).toInt();
            curIdx = findIdx + 1;
            //qDebug() << "cx:" << mLayout.mCX;

            findIdx = packet.indexOf(',', curIdx);
            mLayout.mCY = packet.mid(curIdx, (findIdx-curIdx)).toInt();
            curIdx = findIdx + 1;
            //qDebug() << "cy:" << mLayout.mCY;

            findIdx = packet.indexOf(',', curIdx);
            mLayout.mRow = packet.mid(curIdx, (findIdx-curIdx)).toInt();
            curIdx = findIdx + 1;
            //qDebug() << "row:" << mLayout.mRow;

            findIdx = packet.indexOf(',', curIdx);
            mLayout.mColumn = packet.mid(curIdx, (findIdx-curIdx)).toInt();
            curIdx = findIdx + 1;
            //qDebug() << "column:" << mLayout.mColumn;

            qDebug() << "cx:" << mLayout.mCX << "cy:" << mLayout.mCY << "row:" << mLayout.mRow << "column:" << mLayout.mColumn;

            firstIdx = packet.indexOf('[', curIdx);
            lastIdx = packet.indexOf(']', curIdx);
            while ((-1 < firstIdx) && (-1 < lastIdx)) {
                curIdx = firstIdx + 1;

                Button button;

                findIdx = packet.indexOf(',', curIdx);
                button.mCId = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "cid:" << button.mCId;

                findIdx = packet.indexOf(',', curIdx);
                button.mBId = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "bid:" << button.mBId;

                findIdx = packet.indexOf(',', curIdx);
                button.mRId = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "rid:" << button.mRId;

                findIdx = packet.indexOf(',', curIdx);
                button.mName = packet.mid(curIdx, (findIdx-curIdx));
                curIdx = findIdx + 1;
                //qDebug() << "name:" << button.mName;

                findIdx = packet.indexOf(',', curIdx);
                button.mNotUsed = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "notUsed:" << button.mNotUsed;

                findIdx = packet.indexOf(',', curIdx);
                button.mPos = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "pos:" << button.mPos;

                findIdx = packet.indexOf(',', curIdx);
                button.mX = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "x:" << button.mX;

                findIdx = packet.indexOf(',', curIdx);
                button.mY = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "y:" << button.mY;

                findIdx = packet.indexOf(',', curIdx);
                button.mCX = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "cx:" << button.mCX;

                findIdx = packet.indexOf(',', curIdx);
                button.mCY = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "cy:" << button.mCY;

                findIdx = packet.indexOf(',', curIdx);
                button.mRType = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "rtype:" << button.mRType;

                findIdx = packet.indexOf(',', curIdx);
                button.mStatus = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "status:" << button.mStatus;

                qDebug() << "cid:" << button.mCId << "bid:" << button.mBId << "rid:" << button.mRId
                         << "name:" << button.mName << "notUsed:" << button.mNotUsed << "pos:" << button.mPos
                         << "x:" << button.mX << "y:" << button.mY << "cx:" << button.mCX << "cy:" << button.mCY
                         << "rtype:" << button.mRType << "status:" << button.mStatus;

                mLayout.mButtons.push_back(button);
                firstIdx = packet.indexOf('[', curIdx);
                lastIdx = packet.indexOf(']', curIdx);
            }

            initLayout();
        } else if (!cmd.compare("update")) {
            // $update:[cid,bid,rid,status,],[...],$

            firstIdx = packet.indexOf('[', curIdx);
            lastIdx = packet.indexOf(']', curIdx);
            while ((-1 < firstIdx) && (-1 < lastIdx)) {
                curIdx = firstIdx + 1;

                int cid, bid, rid, status;

                findIdx = packet.indexOf(',', curIdx);
                cid = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "cid:" << cid;

                findIdx = packet.indexOf(',', curIdx);
                bid = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "bid:" << bid;

                findIdx = packet.indexOf(',', curIdx);
                rid = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "rid:" << rid;

                findIdx = packet.indexOf(',', curIdx);
                status = packet.mid(curIdx, (findIdx-curIdx)).toInt();
                curIdx = findIdx + 1;
                //qDebug() << "status:" << status;

                qDebug() << "cid:" << cid << "bid:" << bid << "rid:" << rid << "status:" << status;

                updateStatus(cid, bid, rid, status);
                firstIdx = packet.indexOf('[', curIdx);
                lastIdx = packet.indexOf(']', curIdx);
            }
        } else if (!cmd.compare("sendfile")) {
            // $sendfile:filename,filesize,filedata$
            QString filename, filesize, filedata;

            findIdx = packet.indexOf(',', curIdx);
            filename = packet.mid(curIdx, (findIdx-curIdx));
            curIdx = findIdx + 1;
            //qDebug() << "filename:" << filename;

            findIdx = packet.indexOf(',', curIdx);
            filesize = packet.mid(curIdx, (findIdx-curIdx));
            curIdx = findIdx + 1;
            //qDebug() << "filesize:" << filesize;

            findIdx = packet.indexOf('$', curIdx);
            filedata = packet.mid(curIdx, (findIdx-curIdx));
            curIdx = findIdx + 1;
            //qDebug() << "filedata:" << filedata << filedata.length();

            qDebug() << "filename:" << filename << "filesize:" << filesize << "filedata:" << filedata << filedata.length();

            if (NULL == mActionSettingsDialog) {
                mActionSettingsDialog = new ActionSettingsDialog(&mLayout, &mAction, this);
            }
            mActionSettingsDialog->load(filedata);
            onActionSettingsDialogShow(true);
        } else if (!cmd.compare("error")) {
            QString msg;

            findIdx = packet.indexOf(',', curIdx);
            msg = packet.mid(curIdx, (findIdx-curIdx));
            curIdx = findIdx + 1;
            qDebug() << "msg:" << msg;

            QMessageBox::warning(this, "Error", msg);
        }
    }
}

void DialogMain::onTcpConnectionClosedByServer()
{
    mIsSocketInit = false;
    qDebug() << "onTcpConnectionClosedByServer()";
    mLayout.clear();
    initLayout();
}

void DialogMain::onTcpError(QAbstractSocket::SocketError socketError)
{
    switch (socketError) {
    case QAbstractSocket::RemoteHostClosedError:
        qDebug() << "RemoteHostClosedError";
        break;
    case QAbstractSocket::HostNotFoundError:
        qDebug() << "HostNotFoundError";
        break;
    case QAbstractSocket::ConnectionRefusedError:
        qDebug() << "ConnectionRefusedError";
        break;
    default:
        qDebug() << "onTcpError() : " << mpTcpSoceket->errorString();
        break;
    }

    if (mSocketServer.mAddress.length() && mSocketServer.mPortNum.length()) {
        QTimer::singleShot(10000, this, SLOT(onTcpConnect()));
    }
}


void DialogMain::loadConfig(const QString fileName)
{
    QSettings settings(fileName, QSettings::IniFormat);
    settings.setIniCodec("UTF-8");

    settings.beginGroup("SocketServer");
    mSocketServer.mAddress = settings.value("address", "127.0.0.1").toString();
    mSocketServer.mPortNum = settings.value("portNum", "7271").toString();
    settings.endGroup();

    settings.beginGroup("UserInfo");
    mUserInfo.mUserId = settings.value("userid", "test").toString();
    mUserInfo.mPassword = settings.value("password", "test").toString();
    settings.endGroup();
}

void DialogMain::saveConfig(const QString fileName)
{
    QFile::remove(fileName);
    QSettings settings(fileName, QSettings::IniFormat);
    settings.setIniCodec("UTF-8");

    settings.beginGroup("SocketServer");
    settings.setValue("address", mSocketServer.mAddress);
    settings.setValue("portNum", mSocketServer.mPortNum);
    settings.endGroup();

    settings.beginGroup("UserInfo");
    settings.setValue("userid", mUserInfo.mUserId);
    settings.setValue("password", mUserInfo.mPassword);
    settings.endGroup();
}

void DialogMain::initContextMenu()
{
    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
            this, SLOT(onShowContextMenu(const QPoint&)));
}

void DialogMain::initWidget(){}

void DialogMain::initTcpSocket()
{
    mpTcpSoceket = new QTcpSocket(this);
    connect(mpTcpSoceket, SIGNAL(connected()), this, SLOT(onTcpConnected()));
    connect(mpTcpSoceket, SIGNAL(readyRead()), this, SLOT(onTcpRead()));
    connect(mpTcpSoceket, SIGNAL(disconnected()), this, SLOT(onTcpConnectionClosedByServer()));
    connect(mpTcpSoceket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onTcpError(QAbstractSocket::SocketError)));

    if (mSocketServer.mAddress.length() && mSocketServer.mPortNum.length()) {
        QTimer::singleShot(1000, this, SLOT(onTcpConnect()));
    }
}

void DialogMain::initLayout()
{
    if (ui->scrollArea->takeWidget()) {
        delete ui->scrollArea->takeWidget();
    }

    setMinimumSize(mLayout.mCX, mLayout.mCY);
    ui->scrollArea->setMinimumSize(mLayout.mCX-20, mLayout.mCY-20);
    setMaximumSize(mLayout.mCX, mLayout.mCY);
    ui->scrollArea->setMaximumSize(mLayout.mCX-20, mLayout.mCY-20);
    ui->scrollArea->move(10, 10);
    {
        QRect rect = QApplication::desktop()->availableGeometry();
        int x = (rect.width() - mLayout.mCX) / 2;
        int y = (rect.height() - mLayout.mCY) / 2;
        move(x, y);
    }

    QWidget *client = NULL;
    const int numColumn = mLayout.mColumn;
    if (numColumn) {
        client = new QWidget(this);
        QGridLayout *layout = new QGridLayout(client);

        for (int i=0; i<mLayout.mButtons.size(); i++) {
            int row = mLayout.mButtons[i].mPos / numColumn;
            int column = mLayout.mButtons[i].mPos % numColumn;
            if (mLayout.mRow > row) {
                ButtonRelay *buttonRelay = new ButtonRelay(mLayout.mButtons[i]);
                connect(buttonRelay, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
                mLayout.mButtons[i].mWidget = buttonRelay;

                layout->addWidget(buttonRelay, row, column, Qt::AlignCenter);
            }
        }
        client->setLayout(layout);
    }

    ui->scrollArea->setWidget(client);
}

void DialogMain::updateStatus(int cid, int bid, int rid, int status)
{
    for (int i=0; i<mLayout.mButtons.size(); i++) {
        Button button = mLayout.mButtons.at(i);

        if ((button.mCId == cid) && (button.mBId == bid) && (button.mRId == rid)) {
            mLayout.mButtons[i].mStatus = status;
            ButtonRelay *buttonRelay = (ButtonRelay *)mLayout.mButtons[i].mWidget;
            buttonRelay->setStatus(status);
            break;
        }
    }
}
